package net.omnivention.proxy;

import org.apache.log4j.Logger;

public class HttpRequest {

	public static final String CONNECT = "CONNECT";

	public static final String POST = "POST";

	public static final String GET = "GET";

	private static Logger logger = Logger.getLogger(HttpRequest.class);

	private String method;

	private String resource;

	private String version;

	private HttpHeaders headers;

	private HttpBody body;

	private String host;

	private int port = 80;

	private String protocol;

	public HttpHeaders getHeader() {
		return headers;
	}

	public void setHeader(HttpHeaders header) {
		this.headers = header;
	}

	public HttpBody getBody() {
		return body;
	}

	public void setBody(HttpBody body) {
		this.body = body;
	}

	public String getMethod() {
		return method;
	}

	public void setMethod(String method) {
		this.method = method;
	}

	public String getResource() {
		return resource;
	}

	public void setResource(String resource) {
		this.resource = resource;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	public String toString() {
		return new String(getAsByteArray());
	}

	/**
	 * The request line is first line of the request. For example, 
	 * GET http://www.ebay.com:8080/index.html HTTP/1.0 
	 * or
	 * GET / HTTP/1.1
	 */
	void injectRequestLine(String line) {
		logger.debug(line);
		try {
			String[] fields = line.split(" ");
			this.method = fields[0]; // e.g. GET, POST, CONNECT
			this.resource = fields[1]; // e.g. http://www.ebay.com:8080/index.html, /index.html

			String protocolVersion = fields[2]; // e.g. HTTP/1.1
			String[] protocol_version = protocolVersion.split("/");
			this.protocol = protocol_version[0];
			this.version = protocol_version[1];

			if (method.equals(CONNECT)) {
				int i = resource.indexOf(":");
				if (i > -1) {
					this.port = Integer.parseInt(resource.substring(i + 1, resource.length()));
				}
			} else if (resource.indexOf("http://") > -1) {
				int doubleSlash = resource.indexOf("//");
				int slash = resource.indexOf("/", doubleSlash + 2);
				String host_port = resource.substring(doubleSlash + 2, slash);

				int colon = host_port.indexOf(":");
				if (colon > -1) {
					String p = host_port.substring(colon + 1, host_port.length());
					this.port = Integer.parseInt(p);
					this.resource = resource.substring(slash, resource.length());
				} else {
					this.port = 80;
					this.host = resource.substring(doubleSlash + 2, slash);
					this.resource = resource.substring(slash, resource.length());
				}
			}

		} catch (Exception ex) {
			logger.error("line=" + line);
			logger.error(ex, ex);
		}
	}

	public byte[] getAsByteArray() {
		byte[] requestLine;
		if (method.equals(CONNECT)) {
			requestLine = (method + " " + host + ":" + port + " HTTP/" + version + "\r\n").getBytes();
		} else {
			requestLine = (method + " " + resource + " HTTP/" + version + "\r\n").getBytes();
		}

		byte[] header = (headers + HttpUtility.NEWLINE + HttpUtility.NEWLINE).getBytes();
		byte[] content = body.getAsByteArray();

		byte[] response = new byte[requestLine.length + header.length + content.length];

		int i = 0;
		for (byte b : requestLine) {
			response[i++] = b;
		}

		for (byte b : header) {
			response[i++] = b;
		}

		for (byte b : content) {
			response[i++] = b;
		}

		return response;
	}

	public String getHost() {
		int i = host.indexOf(":");
		if (i > -1) {
			return host.substring(0, i);
		}
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public String getProtocol() {
		return protocol;
	}
}
